package com.storlead.security.config;


import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;

import java.util.*;

/**
 * @Author: timo
 * @Date: 2019/3/20 19:18
 * @Description: 设置当前url访问需要的角色
 * 这里是根据请求进来的url查找需要的角色，然后放入Security上下文中，然后再授权处再进行认证
 */
@Component
public class CustomMetadataSource implements FilterInvocationSecurityMetadataSource {

    AntPathMatcher antPathMatcher = new AntPathMatcher();
    static Map<String, List<String>> roleMap = new HashMap<>();

    /**
     * 设置全局的url资源需要的角色
     */
    static {
        roleMap.put("/index", Arrays.asList("ROLE_ADMIN", "ROLE_USER", "ROLE_ALL"));
        roleMap.put("/detail", Arrays.asList("ROLE_ADMIN", "ROLE_ALL"));
        roleMap.put("/get", Arrays.asList("ROLE_USER", "ROLE_ALL"));
        roleMap.put("/test", Arrays.asList("ROLE_TEST"));
    }

    /**
     *
     * @param o
     * @return
     */
    @Override
    public Collection<ConfigAttribute> getAttributes(Object o) {
        // 当前请求的URL
        String requestUrl = ((FilterInvocation) o).getRequestUrl();

        // 获取角色
        for (String keyUrl : roleMap.keySet()) {
            if (antPathMatcher.match(keyUrl, requestUrl)) {
                List<String> roleCode = roleMap.get(keyUrl);
                String[] values = new String[roleCode.size()];
                for (int i = 0; i < roleCode.size(); i++) {
                    values[i] = roleCode.get(i);
                }
                // 返回当前URL可以访问的角色
                return SecurityConfig.createList(values);
            }
        }
        //没有匹配上的资源，都是登录访问
        return SecurityConfig.createList("ROLE_LOGIN");
    }

    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return FilterInvocation.class.isAssignableFrom(aClass);
    }
}
